<?php

class AuthController extends Zend_Controller_Action
{

    public function init()
    {
    	
    }

    public function indexAction()
    {
    	//read the session.
        $storage = new Zend_Auth_Storage_Session();
		$session = $storage->read();
		//there is no data in session, then direct to login action
		if(!$session){
			$this->_redirect('auth/login');
		}
		//there is data in session, show the user's information
		$this->view->session = $session;
    }
	//For user login
    public function loginAction()
    {
    	//if the user has logged, redirect to index
		if($this->isLoggedIn()) {
			$this->_redirect('auth/index');
		}
		
		require_once APPLICATION_PATH . '/models/DbTable/Users.php';
		require_once APPLICATION_PATH . '/forms/Login.php';
		$usersDB = new Model_DbTable_Users();
		$form = new Application_Form_Login();
		
		//set the blank user form to view
		$this->view->form = $form;
		
		if($this->getRequest()->isPost()){
			if($form->isValid($_POST)){
				//get data from view
				$data = $form->getValues();
				//get data from database
				$auth = Zend_Auth::getInstance();
				$authAdapter = new Zend_Auth_Adapter_DbTable($usersDB->getAdapter(),'users');
				$authAdapter->setIdentityColumn('account')
							->setCredentialColumn('password');
				$authAdapter->setIdentity($data['account'])
							->setCredential($data['password']);
				//validate the account and password according the data of database
				$result = $auth->authenticate($authAdapter);
				if($result->isValid()) {
					//if the validation passed, write the login information to session
					$storage = new Zend_Auth_Storage_Session();
					$sessionData = $authAdapter->getResultRowObject();
					$storage->write($sessionData);
					//if the user is administrator, direct to admin view. If the user is member, direct to member view.
					//If the user belong none of the two type, return error.
					$userType = $sessionData->user_type;
					if("2" === $userType){
						$this->_redirect('auth/admin');
					} else if ("1" === $userType){
						$this->_redirect('message/me');
					} else {
						$this->view->errorMessage ="Invalid user type. Please try again.";
					}
				} else {
					//If the validation failed, direct to signup view.
					$this->_redirect('auth/login');
				}  
			}
		}
    }
	//For user log out
    public function logoutAction()
    {
        //clear the data in session
		$storage = new Zend_Auth_Storage_Session();
        $storage->clear();
        //after logout, direct to login view.
		$this->_redirect('auth/login');
    }
	//For user sign up an account
    public function signupAction() {
    	
		require_once APPLICATION_PATH . '/models/DbTable/Users.php';
		require_once APPLICATION_PATH . '/models/UsersMapper.php';
		require_once APPLICATION_PATH . '/forms/Signup.php';
		
		$usersDB = new Model_DbTable_Users();
		$usersMapper = new Model_UsersMapper();
		$form = new Application_Form_Signup();
		$form->user_type->setValue('1');
		$form->removeElement('currentPassword');
		
		//get the data id from view.
        $request = $this->getRequest();
        $fbAccount = $request->getParam("access_token");
        
        //if it could not get the token from face booke, return login page
        if($fbAccount){
        	$form->fb_account->setValue($fbAccount);
        } else {
        	$this->view->errorMessage('The face book account is invalide, please signup again.');
        	$this->_redirect('/auth/login');
        }
		
		//set the blank signup form to view
		$this->view->form=$form;
		
		if($this->getRequest()->isPost()){
			if($form->isValid($_POST)) {
				//get value from form of view
				$data = $form->getValues();
				//if the password is not equal to confirm password, return error.
				if($data['password'] != $data['confirmPassword']){
					$this->view->errorMessage ="Password and confirm password don't match.";
					return;
				}
				
				$user = new Model_Users();
				$usersMapper->findUserByAccount($data['account'],$user);
				//check if the user name has been registrated, if yes, return error.
				if(!$user){
					$this->view->errorMessage ="the account has already been registered. Please choose another one.";
					return;
				}
				
				//insert the data into database without the confirm password and id, because confirm password does
				//not exist in database and id is generated automately.
				unset($data['confirmPassword']);
				$usersDB->insert($data);
				//after registration, direct to login action
				$this->_redirect('auth/login');
			}
		}
    }
    //send a request to face book to get the token
    //It used automaticly when the user sign up
    public function fbAction() {
    	
    	$appId = '194530857249703'; //our application id of face book.
    	$scope= 'email,offline_access,publish_checkins';//access the permissions: email, offline_access, checkins from user.
    	$secret = '42f587060ed6f1e2138a5445534aec39';//our application secret id of face book.
    	$uri = 'http://hkwhatever.com/auth/fb';//return url.
    	
    	$code = $_REQUEST["code"];
    	
    	//if the code is null, get code from face book.
    	if(empty($code)){
    		$getCodeUrl = "https://www.facebook.com/dialog/oauth?client_id=".$appId.
    					  "&redirect_uri=".urlencode($uri).
    					  "&scope=".$scope;
    		echo("<script> top.location.href='" . $getCodeUrl . "'</script>");
    	} else {
    		//if the code is existed, get user token with the code.
    		$getTokenUrl ="https://graph.facebook.com/oauth/access_token?client_id=".$appId.
        				 "&redirect_uri=".($uri).
        				 "&client_secret=".$secret.
        				 "&code=".$code;
    		
    		//connect face book with curl which recommand by face book.
    		$ch = curl_init();
    		$options = array(
				CURLOPT_URL => $getTokenUrl,
				CURLOPT_HEADER => false,
				CURLOPT_SSL_VERIFYPEER => false,
				CURLOPT_SSL_VERIFYHOST => false,
				CURLOPT_RETURNTRANSFER => true
			);
    		curl_setopt_array($ch, $options);
			$data = curl_exec($ch);
			curl_close($ch);
			
			//if it could get the token, direct the signup page with token.
			if(!empty($data) && 'access_token' == substr($data, 0, 12)){
		    	$this->_redirect("/auth/signup?".$data);
			} else {
				//if it could not get token, back to login page.
				$this->view->errorMessage('Your face booke request denied, please try again or check your face book statues');
				$this->_redirect("/auth/login");
			}
    	}
    	
    }
    //user edit their information
	public function editAction() {
		
		require_once APPLICATION_PATH .'/forms/Signup.php';
		
		//if the user has not login, direct to login view
		$storage = new Zend_Auth_Storage_Session();
		$data = $storage->read();
		if(!$data){
			$this->_redirect('auth/login');
		}
		
		$id = $_REQUEST['user_id'];
		
		//if the user id param exsiting, it means editing others info.
		if($id){
			//if editing others info., it should be the admin role account.
			if("2" != $data->user_type){
				$this->view->errorMessage = "You can not modify the account info.";
				return;
			}
		} else {
			//read the user id type from session.
			$id = $data->user_id;
		}
		
		$users = new Model_Users();
		$usersDB = new Model_DbTable_Users();
		$usersMapper = new Model_UsersMapper();
		$form = new Application_Form_Signup();
		$mapper = new Model_UsersMapper();
		
		$form->register->setLabel('Edit');
		$form->account->setAttrib('readonly', true); //the account should not be modify.
		
		//find the user information from database with id
		$mapper->find($id, $users);
		
		//pop the data to view.
		$popUser = array(
					'user_type' => $users->getUser_type(),
					'fb_account' => $users->getFb_account(),
					'account' => $users->getAccount(),
					'name' => $users->getName(),
					'tel' => $users->getTel(),
					'university' => $users->getUniversity(),
					'major' => $users->getMajor(),
					'address' => $users->getAddress(),
					'birthday' => $users->getBirthday(),
		);
		$form->populate($popUser);
		
		//set the registration form to form of view.
		$this->view->form = $form;
		
		if($this->getRequest()->isPost()){
			if($form->isValid($_POST)) {
				//get value from view
				$data = $form->getValues();
				//if the password is not equal to confirm password, return error.
				if($users->getPassword() != $data['currentPassword']){
					$this->view->errorMessage ="Password is not correct.";
					return;
				}
				//if the password is not equal confirmpassword, return error.
				if($data['password'] != $data['confirmPassword']){
					$this->view->errorMessage ="Password and confirm password don't match.";
					return;
				}
				
				//update the information of user to database.
				unset($data['currentPassword']);
				unset($data['confirmPassword']);
				$usersDB->update($data, array('user_id=?'=>$id));
				$session = $storage->read();
				//if it is common user, relogin after modify the infomation.
				if(1==$session->user_type){
					$this->_redirect('auth/logout');
				} else {
					$this->_redirect('auth/admin');
				}
			}
		}
	}
	//action for the admin users
	public function adminAction() {
		
		//if the user has not login, direct to login view
		$storage = new Zend_Auth_Storage_Session();
		$data = $storage->read();
		if(!$data){
			$this->_redirect('auth/login');
		}
		
		$usersDB = new Model_DbTable_Users();
		//get all users information from database
		$entries = $usersDB->fetchAll();
		//set the users infromation to view.
		$this->view->entries = $entries;
	}
	//action of delete user information
	public function delAction() {
		
		//get the user id form parameter of view
		$id = $_REQUEST['user_id'];
		//delete the information of the user from database.
		$userDB = new Model_DbTable_Users();
		$usersMapper = new Model_UsersMapper();
		$user = new Model_Users();
		$usersMapper->find($id, $user);
		//if the deleted user is admin role user, it could not be deleted.
		if("2" === $user->getUser_type()){
			$this->_helper->json("deleted failed, because you could not delete the admin role user.");
			return;
		}
		$userDB->delete(array('user_id=?'=>$id));
		//direct to admin view.
		$this->_helper->json("success deleted");
	}
	//check if the user has logged
	public static function isLoggedIn() {
		return Zend_Auth::getInstance()->hasIdentity();
	}

}
